﻿/*******************************************************
 * 
 * 作者：胡庆访
 * 创建时间：20130326 15:35
 * 说明：此文件只包含一个类，具体内容见类型注释。
 * 运行环境：.NET 4.0
 * 版本号：1.0.0
 * 
 * 历史记录：
 * 创建文件 胡庆访 20130326 15:35
 * 
*******************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace MSDNConverter
{
    public class HtmlConverter
    {
        private CacheReader _imageReader;

        public HtmlConverter(CacheReader imageReader)
        {
            this._imageReader = imageReader;
        }

        public Article Convert(RawArticle raw)
        {
            var item = new Article
            {
                Raw = raw,
            };

            ConvertRecur(item);

            return item;
        }

        private void ConvertRecur(Article item)
        {
            ReadContent(item);

            var listNo = item.ListNo ?? string.Empty;
            if (listNo.Length > 0) { listNo += "."; }

            var children = item.Raw.Children;
            for (int i = 0, c = children.Count; i < c; i++)
            {
                var rawChild = children[i];

                var child = new Article
                {
                    Raw = rawChild,
                    ListNo = listNo + (i + 1)
                };

                ConvertRecur(child);

                item.Children.Add(child);
            }
        }

        private static readonly string TitleMark = "___TitleStart___";
        private static readonly string CodeMark_Start = "___CodeStart___";
        private static readonly string CodeSpace = "___CodeSpace___";
        private static readonly string CodeMark_End = "___CodeEnd___";
        private static readonly string ParagraphSplitter = "___NewLine___";
        private static readonly string ImageMark = "___ImageStart___";

        private void ReadContent(Article item)
        {
            var content = ParseContent(item.Raw.RawHtml);

            ReadContent(item, content);
        }

        private string ParseContent(string html)
        {
            var msMatch = Regex.Match(html, @"<div id=""mainSection"">(?<mainSection>.+)</div>\s*<div id=""contentFeedback""", RegexOptions.Singleline);
            var content = msMatch.Groups["mainSection"].Value;

            //保留代码中的换行，并对代码做标记。
            var matches = Regex.Matches(content, @"<pre>(?<code>.+?)</pre>", RegexOptions.Singleline);
            foreach (Match match in matches)
            {
                var matchValue = match.Groups["code"].Value.Trim();

                //保留代码中的换行
                var value = hxy.TextFormatter.ReNewLine.Replace(matchValue, ParagraphSplitter);

                //代码的前后标记。
                value = ParagraphSplitter + CodeMark_Start + value + CodeMark_End + ParagraphSplitter;

                //保留代码中空格。
                value = value.Replace(" ", CodeSpace);

                //在内容中替换。
                content = content.Replace(matchValue, value);
            }

            //把段落变为新的换行符
            content = content.Replace("</p>", "</p>" + ParagraphSplitter);

            //对小标题做标记，并换行。
            content = Regex.Replace(content,
                @"<span class=""LW_CollapsibleArea_Title"">(?<title>[^<]+)</span>",
                ParagraphSplitter + TitleMark + @"${title}" + ParagraphSplitter//同时加上换行，形成段落
                );

            //对图片做标记，并换行。
            content = Regex.Replace(content,
                @"<img.+?src=""(?<src>[^""]+)"".+?/>",
                ParagraphSplitter + ImageMark + @"${src}" + ParagraphSplitter//同时加上换行，形成段落
                );

            //去除所有 html 标签
            content = Regex.Replace(content, "<[^<>]+>", string.Empty);

            //去除多余的空白
            content = Regex.Replace(content, "\\s+", " ");

            //文本处理。
            content = content.Replace("&lt;", "<").Replace("&gt;", ">");//.Replace("$nbsp;", " ");
            return content;
        }

        private void ReadContent(Article item, string content)
        {
            var paragraphContentList = content.Split(new string[] { ParagraphSplitter }, StringSplitOptions.RemoveEmptyEntries);
            foreach (var paragraphContent in paragraphContentList)
            {
                var pContent = paragraphContent.Trim();

                //还原代码中的空白
                pContent = pContent.Replace(CodeSpace, " ");

                var p = new ArticleParagraph();
                if (pContent.StartsWith(ImageMark))
                {
                    var src = pContent.Substring(ImageMark.Length);

                    var imageFile = this._imageReader.GetImageFile(src);

                    p.IsImage = true;
                    p.Content = imageFile;
                }
                else
                {
                    if (pContent.StartsWith(CodeMark_Start))
                    {
                        p.IsCodeStart = true;
                        pContent = pContent.Substring(CodeMark_Start.Length);
                    }

                    if (pContent.EndsWith(CodeMark_End))
                    {
                        p.IsCodeEnd = true;
                        pContent = pContent.Substring(0, pContent.Length - CodeMark_End.Length);
                    }

                    if (pContent.StartsWith(TitleMark))
                    {
                        p.IsSubTitle = true;
                        pContent = pContent.Substring(TitleMark.Length);
                    }
                    p.Content = pContent;
                }

                item.Paragraphs.Add(p);
            }
        }
    }
}
